package com.fingard.dsp.bank.directbank.bob01;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.DirectBase;
import com.fingard.net.WebRequest;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;
import com.fingard.util.TransIDHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;


public class BOB01Base extends DirectBase {

    private static Map<String, String> SessionIDMap = new ConcurrentHashMap<String, String>();
    private static Map<String, Object> LoginInfoMap = new ConcurrentHashMap<String, Object>();

    protected void loginDeal() {

        synchronized (LoginInfoMap) {
            if (!LoginInfoMap.containsKey(bankFront.serverIP)) {
                LoginInfoMap.put(bankFront.serverIP, DateHelper.addMinutes(new Date(), -30));
            }
            if (!SessionIDMap.containsKey(bankFront.serverIP)) {
                SessionIDMap.put(bankFront.serverIP, "");
            }
            if (((Date) LoginInfoMap.get(bankFront.serverIP)).before(DateHelper.addMinutes(new Date(), -5)))//5分钟未操作
            {
                WriteBankLogLn("进行登录");
                //签退
                if (!StringHelper.isNullOrEmpty(SessionIDMap.get(bankFront.serverIP))) {
                    this.logout();
                }
                //登陆
                String sessionid = this.login();
                if (sessionid != null) {
                    LoginInfoMap.put(bankFront.serverIP, new Date());
                    SessionIDMap.put(bankFront.serverIP, sessionid);
                } else {
                    LoginInfoMap.put(bankFront.serverIP, DateHelper.addMinutes(new Date(), -30));//需再登录
                }
            } else {
                LoginInfoMap.put(bankFront.serverIP, new Date());
            }
        }

    }

    protected String login() {
        String sessionid = null;

        try {

            XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
            xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"" + getCharset() + "\"?>");
            xmlWriter.writeStartElement("BCCBEBankData");
            xmlWriter.writeStartElement("opReq");
            xmlWriter.writeElementString("opName", "CebankUserLogonOp");
            xmlWriter.writeElementString("serialNo", getQryTransID());
            xmlWriter.writeElementString("reqTime", Format.Date8Format.format(new Date()));
            xmlWriter.writeStartElement("ReqParam");
            xmlWriter.writeElementString("userID", bankFront.loginName);
            xmlWriter.writeElementString("userPWD", bankFront.loginPasswd);
            xmlWriter.writeEndElement();
            xmlWriter.writeEndElement();
            xmlWriter.writeEndDocument();
            String p_reqStr = xmlWriter.toXmlString();

            String signRetStr = dataSignature(p_reqStr);
            signRetStr = URLEncoder.encode(signRetStr, getCharset());
            String tmpAddrLogin = "http://" + bankFront.serverIP + ":" + bankFront.serverPort + "/servlet/com.bccb.inbs.api.servlet.APISessionReqServlet";
            String sendInfo = "netType=3&reqData=" + signRetStr;
            WriteBankLogStep2(sendInfo);
            WebRequest loginWebRequest = new WebRequest(tmpAddrLogin);
            loginWebRequest.setConnectTimeout(10000);
            loginWebRequest.setRequestProperty("User-Agent", "API");

            byte[] tmpLoginBytes = sendInfo.getBytes(getCharset());
            String[] retStr = loginWebRequest.upload(tmpLoginBytes, getCharset());
            WriteBankLogStep3(retStr[1]);
            if (retStr[0].length() == 0) {
                //解析返回数据
                String[] strArray = retStr[1].split("\\|");
                if (strArray.length == 2) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(strArray[1], tmpSbMsg);
                    if (tmpBkReader != null) {
                        String tmprspcod = tmpBkReader.getFirstText("/BCCBEBankData/opRep/retCode");
                        String tmprspmsg = tmpBkReader.getFirstText("/BCCBEBankData/opRep/errMsg");
                        if ("0".equals(tmprspcod) || "".equals(tmprspcod.replace("0", ""))) {
                            sessionid = strArray[0];
                            bankFront.loginFailCount = 0;
                            WriteBankLogLn("登录成功");
                        } else {
                            bankFront.loginFailCount = bankFront.loginFailCount + 1;
                            WriteBankLogLn("登录失败1：" + tmprspmsg);
                        }
                    } else {
                        bankFront.loginFailCount = bankFront.loginFailCount + 1;
                        WriteBankLogLn("登录失败");
                    }
                } else {
                    bankFront.loginFailCount = bankFront.loginFailCount + 1;
                    WriteBankLogLn("登录失败2：" + retStr[1]);
                }
            } else {
                WriteBankLogLn("登录失败3：" + retStr[1]);
            }
        } catch (Exception e) {
            WriteBankLogLn("登录异常：" + e.getMessage());
            e.printStackTrace();
        }
        return sessionid;

    }

    protected void logout() {
        try {
            String tmpAddrLogin = "http://" + bankFront.serverIP + ":" + bankFront.serverPort + "/servlet/com.bccb.inbs.api.servlet.APISignOffReqServlet";
            String sendInfo = "dse_sessionId=" + SessionIDMap.get(bankFront.serverIP);
            WebRequest loginWebRequest = new WebRequest(tmpAddrLogin);
            loginWebRequest.setConnectTimeout(10000);
            loginWebRequest.setRequestProperty("User-Agent", "API");

            byte[] tmpLoginBytes = sendInfo.getBytes(getCharset());
            loginWebRequest.upload(tmpLoginBytes, getCharset());
        } catch (Exception e) {
            WriteBankLogLn("签退异常：" + e.getMessage());
            e.printStackTrace();
        }
    }

    private static TransIDHelper idHelper = new TransIDHelper(1, 999);
    protected String getQryTransID() {
        Date tmpDateNow = new Date();
        return Format.DateTime12Year2Format.format(tmpDateNow) + idHelper.getNextIDStr();
    }

    protected String getCharset() {
        return getBankConfig().getCharset("GBK");
    }

    protected void writeCommonHeader(XmlTextWriter xmlWriter) throws Exception {
        this.loginDeal();
        xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"" + getCharset() + "\"?>");
        xmlWriter.writeStartElement("BCCBEBankData");
    }

    protected String[] sendToBank(String p_reqStr, String opName) throws UnsupportedEncodingException {
        WriteBankLogStep2(p_reqStr);
        String signRetStr = p_reqStr;
        if ("CebankPayWithNewPrecontractOp".equals(opName) || "CebankGZBatchPayNewOp".equals(opName) || "CebankDKBatchPayNewOp".equals(opName)) {
            signRetStr = dataSignature(signRetStr);
        }
        signRetStr = URLEncoder.encode(signRetStr, getCharset());

        String tmpAddrUrl = "http://" + bankFront.serverIP + ":" + bankFront.serverPort + "/servlet/com.bccb.inbs.api.servlet.APIReqServlet";

        String sendInfo = "dse_sessionId=" + SessionIDMap.get(bankFront.serverIP) + "&opName=" + opName + "&reqData=" + signRetStr;
        WriteBankLogLn("2.提交银行的地址：" + tmpAddrUrl);
        WriteBankLogStep2(sendInfo);
        WebRequest tmpWebRequest = new WebRequest(tmpAddrUrl);
        tmpWebRequest.setConnectTimeout(10000);
        tmpWebRequest.setRequestProperty("User-Agent", "API");

        byte[] tmpUpBytes = sendInfo.getBytes(getCharset());
        String[] retStr = tmpWebRequest.upload(tmpUpBytes, getCharset());

        if (retStr[0].length() == 0 && retStr[1].contains("非法SESSION或SESSION已超时!")) {
            LoginInfoMap.put(bankFront.serverIP, DateHelper.addMinutes(new Date(), -30));//需再登录
        }
        WriteBankLogStep3(retStr[1]);
        return retStr;
    }

    protected boolean isActiveRetCode(String retCode) {
        if (retCode != null&&retCode.equals("0")) {
                bankFront.lastVisitTime = new Date();
                return true;
        }
        return false;
    }

    //签名
    //返回是签名后信息
    //签名失败返回null
    private String dataSignature(String reqData) {
        String signRetStr = null;
        try {
            String tmpAddrSign = "http://" + bankFront.serverIP + ":" + bankFront.signPort;
            WriteBankLogLn("签名地址为：" + tmpAddrSign);
            WebRequest tmpWebRequest = new WebRequest(tmpAddrSign);

            String contentLength = Integer.toString(reqData.length());
            tmpWebRequest.setRequestProperty("User-Agent", "API");
            tmpWebRequest.setRequestProperty("Content-Length", contentLength);
            tmpWebRequest.setRequestProperty("Content-Type", "INFOSEC_SIGN/1.0");
            WriteBankLogLn("进行签名的数据为：" + reqData);
            byte[] tmpUpBytes = reqData.getBytes(getCharset());
            String[] tmpSignStr = tmpWebRequest.upload(tmpUpBytes, getCharset());
            WriteBankLogLn("签名返回结果为：" + tmpSignStr[1]);
            int startResult = tmpSignStr[1].indexOf("<html>");
            signRetStr = tmpSignStr[1].substring(startResult);
            int nStartResult = signRetStr.indexOf("<sign>") + 6;
            int nEndResult = signRetStr.lastIndexOf("</sign>");
            signRetStr = signRetStr.substring(nStartResult, nEndResult);
            signRetStr = signRetStr.replace("\n", "");

        } catch (Exception e) {
            e.printStackTrace();
        }

        return signRetStr;
    }

}
